/********************************************************
* filename : dmp2pif.c					*
* startdate : Mon, November 30 2009			*
* lastupdate : Thu, April 1 2010			*
* author : Limthong K. Kriangkrai			*
* location : NII Tokyo, Japan				*
*							*
* Convert a dump file to a packet information file	*
********************************************************/

//#define __USE_BSD
#include <netinet/ip.h>
#define __FAVOR_BSD
#include <netinet/tcp.h>
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <netinet/if_ether.h>
#include <netinet/ether.h>
#include <arpa/inet.h>

//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
#include <time.h>
//#include <math.h>
#include <pcap.h>

void packethandler(u_char *, const struct pcap_pkthdr *, const u_char *);

int main(int argc, char*argv[]) {
	//To check arguments.
	if(argc < 2 || argc > 3) {
		printf("usage: %s <dumpfile> [filter]\n", argv[0]);
		return -1;
	}//End check arguments.
	char *dumpfile = argv[1];
	char *filter = argv[2];

	//Read packet from dump file.
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *handle;
	struct bpf_program fcode; //For hold compiled program.

	//Open dump file.
	if((handle = pcap_open_offline(dumpfile, errbuf)) == NULL) {
		fprintf(stderr, "Error opening dumpfile\n");
		return -1;
	}

	//Compile the filter.
	if(pcap_compile(handle, &fcode, filter, 1, 0xffffff) < 0) {
		fprintf(stderr, "Unable to compile the packet filter. Check the syntax.\n");
		return -1;
	}

	//Set the filter.
	if(pcap_setfilter(handle, &fcode) < 0) {
		fprintf(stderr, "Error setting filter.\n");
		return -1;
	}

	//Read and dispatch packets util EOF is reached.
	pcap_loop(handle, 0, packethandler, NULL);

	//Close capture file.
	pcap_close(handle);

	return 0;
}

void packethandler(u_char *unused, const struct pcap_pkthdr *header, const u_char *packet) {
	struct tm *packettime;
	char packettimestr[64];
	int timestamp;
	int interval = 1000000;

	struct ether_header *ethhdr = NULL;
	struct ip *iphdr = NULL;
	struct tcphdr *tcphdr = NULL;
	ethhdr = (struct ether_header *)(packet);
	iphdr = (struct ip *)(packet+14);
	tcphdr = (struct tcphdr *)(packet+14+20);

	packettime = localtime(&header->ts.tv_sec);
	//strftime(packettimestr, sizeof(packettimestr), "%d-%b-%Y-%H:%M:%S %Z", packettime);
	strftime(packettimestr, sizeof(packettimestr), "%H:%M:%S %Z", packettime);
	timestamp = (packettime->tm_hour*60*60)+(packettime->tm_min*60)+(packettime->tm_sec)+(header->ts.tv_usec/interval);

	printf("%s %ld, %d\t", packettimestr, header->ts.tv_usec, timestamp);
	printf("%s ", inet_ntoa(iphdr->ip_src));
	printf("%s ", inet_ntoa(iphdr->ip_dst));
	printf("%d ", ntohs(tcphdr->th_sport));
	printf("%d ", ntohs(tcphdr->th_dport));
	printf("%d\n", header->len);
	//printf("%s ", ether_ntoa((struct ether_addr *)&ethhdr->ether_shost));
	//printf("%s\n", ether_ntoa((struct ether_addr *)&ethhdr->ether_dhost));
}
